/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Monopol.Events;

import ClientBL.Event;
import Monopol.MonopolyGame;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 *
 * @author Assaf
 */
public class RefreshMonopolyEvents extends TimerTask {

    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
    private final Lock read = readWriteLock.readLock();
    private final Lock write = readWriteLock.writeLock();
    private List<Event> gameEvents;
    private Boolean hasChange = false;
    private MonopolyGame myGame;
    private MonopolyGameEvents monopolEvents;
    private Iterator<Event> evtIterator;

    public RefreshMonopolyEvents(List<Event> eventsList) {
	// Save the Game Events List
	gameEvents = Collections.synchronizedList(eventsList);
	// Create a New Monopoly Events Instance
	monopolEvents = MonopolyGameEvents.getInstance();
    }

    public RefreshMonopolyEvents(List<Event> eventsList, MonopolyGame parentClass) {
	this(eventsList);
	myGame = parentClass;
    }


    @Override
    public synchronized void run() {
	// Create a New Event List
	List<Event> events = null;
	// Verify that the Monopoly Events is not Empty
	if (monopolEvents != null) {
	    // Get all the Events from the Server
	    events = monopolEvents.getEvents();
	}
	// Create a new Copy Of the Current Events
	List<Event> copyEvents = new ArrayList<Event>();
	// Lock for Exclusive Read
	read.lock();
	try {
	    // Get the Iterator of the Current List
	    Iterator<Event> itr = gameEvents.iterator();
	    // Iterate on the Events
	    while (itr.hasNext()) {
		// Add the Events to the Copy List
		copyEvents.add(itr.next());
	    }
	    // Add all the Server Events to the Copy List
	    copyEvents.addAll(events);
	} finally {
	    // Unlock the Read
	    read.unlock();
	}

	// Lock the Class - Allow Write Only
	write.lock();
	try {
	    // Replace the Current Event Array with the New Copy
	    gameEvents = copyEvents;
	    // Notify on the Change
	    hasChange = true;
	} finally {
	    // Unlock the Class - Allow Read
	    write.unlock();
	}
    }

    /**
     * Get all the Game Events
     * @return The Current Game Event
     */
    public synchronized List<Event> getEvents() {
	// Lock the Class - Allow Read Only
	read.lock();
	try {
	    return gameEvents;
	} finally {
	    // Unlock the Class - Allow Write
	    read.unlock();	    
	}

    }

    public Iterator<Event> getIterator(){
	if(evtIterator == null){
	    evtIterator = gameEvents.iterator();
	}
	return evtIterator;
    }

    /**
     * Remove an Event from the Game Events Array
     * @param evt The Event to Remove
     */
    public synchronized void removeEvent(Iterator<Event> removeIter) {
	// Lock the Class - Allow Write Only
	write.lock();
	try {
//	    gameEvents.remove(evt);
	    removeIter.remove();
	    removeIter.notifyAll();
	} finally {
	    // Unlock the Class - Allow Read
	    write.unlock();
	}
    }

    public Boolean hasChanged() {
	Boolean res;
	if (hasChange) {
	    // Set the Result to True - A Checnge has been made
	    res = true;
	    // Init the Local Parameter to False - Wait for the Next Change
	    hasChange = false;
	} else {
	    // No Change was made
	    res = false;
	}
	// Return the Result
	return res;

    }
  
}
